﻿using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using ZHWL.Model;

namespace ZHWL
{
    public partial class MainWindow : Window
    {
        private readonly DispatcherTimer dispatcherTimer;
        private readonly Vbarapi vbarapi;
        private readonly AppSettings settings;
        public MainWindow(IOptions<AppSettings> settings)
        {
            InitializeComponent();
            this.settings = settings.Value;
            this.WindowState = WindowState.Normal;
            this.WindowStyle = WindowStyle.None;
            this.ResizeMode = ResizeMode.NoResize;
            //this.Topmost = true;
            this.Left = 0.0;
            this.Top = 0.0;
            this.Width = SystemParameters.PrimaryScreenWidth;
            this.Height = SystemParameters.PrimaryScreenHeight;

            dispatcherTimer = new DispatcherTimer();
            // 当间隔时间过去时发生的事件
            dispatcherTimer.Tick += (s, e) =>
            {
                this.tBlockTime.Text = DateTime.Now.ToString("yyyy-MM-dd  dddd");
                this.tBlockTime2.Text = DateTime.Now.ToString("HH:mm:ss");
            };
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1);
            dispatcherTimer.Start();

            vbarapi = new Vbarapi();

            //初始化全局控制类
            //Helper.animationControlAction = (isStart) => Dispaly(View.WaitingScan);
            Helper.switchViewAction = (v) => Dispaly(v);
            Helper.scanAction = (open) =>
            {
                vbarapi.controlScan(open);
                vbarapi.backlight(open);
            };
            Helper.countdownRemainingEvent = (remaining) =>
            {
                txtCountdown.Text = $"{remaining}";
                SuccessCountdown.Text = $"{remaining}";
                FailureCountdown.Text = $"{remaining}";
            };
        }

        private void Button_Click1(object sender, RoutedEventArgs e)
        {
            Log.Logger.Information("开始...");
            if (!vbarapi.openDevice())
            {
                Helper.StartAnimation(settings.FailureCountdown, () =>
                {
                    Dispaly(View.Failure);
                    FailureText.Text = "设备连接失败";
                }, (isTimeout) => Helper.Back2Home());
                return;
            }
            //倒计时三十秒，期间展示扫码动画。
            Helper.StartAnimation(settings.WaitCountdown, () => Dispaly(View.WaitingScan), (isTimeout) => Helper.Back2Home());
            //打开扫码设备
            Helper.Scan(true);
            Log.Logger.Information("开启扫描...");
            Task.Run(() =>
            {
                var flag = true;
                do
                {
                    var result = Decoder();
                    if (!string.IsNullOrEmpty(result))
                    {
                        try
                        {
                            //关闭扫码设备
                            Helper.Scan(false);
                            //扫码成功取得结果，停止播放扫码动画
                            Dispatcher.Invoke(Helper.StopAnimation);
                            Dispatcher.Invoke(() => Helper.switchViewAction.Invoke(View.Loading));
                            Log.Logger.Information($"二维码：{result}");
                            if (result.Length < 15)
                            {
                                Dispatcher.Invoke(() =>
                                {
                                    Helper.StartAnimation(settings.FailureCountdown, () =>
                                    {
                                        Dispaly(View.Failure);
                                        FailureText.Text = "二维码长度错误";
                                    }, (isTimeout) => Helper.Back2Home());
                                });
                            }
                            result = result.Substring(0, 12);
                            var response = Queue(new QueueRequest()
                            {
                                deliveryCode = result,
                                thjType = settings.Factory
                            });
                            if(response != null)
                            {
                                if (response.success)
                                {
                                    Dispatcher.Invoke(() =>
                                    {
                                        Helper.StartAnimation(settings.SuccessCountdown, () =>
                                        {
                                            Dispaly(View.Success);
                                            SuccessText.Text = response.msg;
                                        }, (isTimeout) => Helper.Back2Home());
                                    });
                                }
                                else {
                                    Dispatcher.Invoke(() =>
                                    {
                                        Helper.StartAnimation(settings.FailureCountdown, () =>
                                        {
                                            Dispaly(View.Failure);
                                            FailureText.Text = response.msg;
                                        }, (isTimeout) => Helper.Back2Home());
                                    });
                                }
                            }
                            
                            flag = false;
                        }
                        catch (Exception e)
                        {
                            Log.Logger.Error(e, e.Message);
                            Dispatcher.Invoke(() =>
                            {
                                Helper.StartAnimation(settings.FailureCountdown, () =>
                                {
                                    Dispaly(View.Failure);
                                    FailureText.Text = "服务器异常,请联系管理员";
                                }, (isTimeout) => Helper.Back2Home());
                            });
                        }
                    }
                }
                while (flag);
            });
        }
        private void Button_Click2(object sender, RoutedEventArgs e)
        {
        }
        private void Return_Btn(object sender, RoutedEventArgs e)
        {
            Helper.Back2Home();
        }

        bool isscan = true;
        private void btnBackToHome_Click(object sender, RoutedEventArgs e)
        {
            //isscan = !isscan;
            //var saomaodonghua = String.Join("", AppDomain.CurrentDomain.BaseDirectory, @"Images\扫码动画.gif");
            //var jiazaidonghua = String.Join("", AppDomain.CurrentDomain.BaseDirectory, @"Images\Loading.gif"); 
            //WpfAnimatedGif.ImageBehavior.SetAnimatedSource(ImgPlayer, new BitmapImage(new Uri(isscan ?saomaodonghua : jiazaidonghua ,UriKind.Absolute))); 
            Helper.Back2Home();
        }

        private string Decoder()
        {
            if (vbarapi.getResultStr(out byte[] result, out int size))
            {
                string msg = System.Text.Encoding.Default.GetString(result);
                byte[] buffer = Encoding.UTF8.GetBytes(msg);
                return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            }
            else
            {
                return null;
            }
        }
        private void Dispaly(View v)
        {
            home.Visibility = Visibility.Collapsed;
            wait.Visibility = Visibility.Collapsed;
            home2.Visibility = Visibility.Collapsed;
            home3.Visibility = Visibility.Collapsed;
            loading.Visibility = Visibility.Collapsed;
            success.Visibility = Visibility.Collapsed;
            failure.Visibility = Visibility.Collapsed;
            switch (v)
            {
                case View.Home:
                    home.Visibility = Visibility.Visible;
                    break;
                case View.WaitingScan:
                    wait.Visibility = Visibility.Visible;
                    break;
                case View.Details:
                    home2.Visibility = Visibility.Visible;
                    break;
                case View.Print:
                    home3.Visibility = Visibility.Visible;
                    break;
                case View.Loading:
                    loading.Visibility = Visibility.Visible;
                    break;
                case View.Success:
                    success.Visibility = Visibility.Visible;
                    break;
                case View.Failure:
                    failure.Visibility = Visibility.Visible;
                    break;
            }
        }
        private QueueResponse Queue(QueueRequest queueRequest)
        {
            Log.Logger.Information("请求开始...");
            string responseStr;
            try
            {
                var client = new HttpClient
                {
                    Timeout = TimeSpan.FromSeconds(1)
                };
                HttpContent httpContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(queueRequest));
                httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                var response = client.PostAsync($"{settings.Url}/jwell-saas-zhwl-client/api/thjQueue/lineUp", httpContent).Result;
                responseStr = response.Content.ReadAsStringAsync().Result;
                Log.Logger.Information(responseStr);
                return Newtonsoft.Json.JsonConvert.DeserializeObject<QueueResponse>(responseStr);
            }
            catch (Exception e)
            {
                Log.Logger.Error(e, e.Message);
                throw e;
            }
        }

    }

    public static class Helper
    {
        private static int countdownRemaining = 0;//倒计时剩余时间
        private static bool isAnimationPlaying = false;
        private static DispatcherTimer timer;
        private static Action<bool> countdownStopCallback;
        public static Action<View> switchViewAction;
        public static Action<bool> scanAction;
        public static Action<bool> animationControlAction;
        public static Action<int> countdownRemainingEvent;

        static Helper()
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += (s, e) =>
            {
                //间隔一秒刷新剩余时间
                if (countdownRemaining > 1)
                {
                    countdownRemaining -= 1;
                    countdownRemainingEvent?.Invoke(countdownRemaining);
                }
                else
                    StopAnimation();
            };
        }


        //TODO 显示关闭倒计时动画
        public static void StartAnimation(int interval, Action view, Action<bool> stopCallback = null)
        {
            if (isAnimationPlaying)
                return;
            isAnimationPlaying = true;
            countdownRemaining = interval;
            countdownStopCallback = stopCallback;
            countdownRemainingEvent?.Invoke(countdownRemaining);
            //显示并循环播放扫码动画
            //animationControlAction?.Invoke(true);
            view?.Invoke();
            timer.Start();
        }

        public static void StopAnimation()
        {
            if (!isAnimationPlaying)
                return;

            isAnimationPlaying = false;

            //停止播放扫码动画并隐藏
            //animationControlAction?.Invoke(false);

            timer.Stop();
            countdownStopCallback?.Invoke(countdownRemaining == 0);//is timeout
        }

        //TODO 回到首页
        public static void Back2Home()
        {
            Scan(false);
            StopAnimation();
            switchViewAction?.Invoke(View.Home);
        }

        //TODO 打开关闭扫描设备
        public static void Scan(bool isOpen)
        {
            scanAction?.Invoke(isOpen);
        }
    }

    public enum View
    {
        Home = 1,
        WaitingScan = 2,
        Details = 3,
        Print = 4,
        Loading = 5,
        Success = 6,
        Failure = 7,
    }
}
